package com.itheima.exception;

import com.itheima.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.HandlerMethodValidationException;

import java.util.List;
import java.util.stream.Collectors;

//info,debug,error
@Slf4j
@RestControllerAdvice // 这是一个全局异常处理器
public class GlobalExceptionHandler {

    // 捕获的异常交给这个方法来处理
    @ExceptionHandler
    //方法的参数类型就是要捕获的异常
    public Result handleException(Exception e){
        log.error("发生未知异常.", e);// 记录异常的格式
        return Result.error("发生未知异常，请稍后重试!");
    }

    @ExceptionHandler
    //方法的参数类型就是要捕获的异常
    public Result handleDuplicateKeyException(DuplicateKeyException e){
        log.error("发生未知异常.", e);// 记录异常的格式
        //Duplicate entry 'nazha' for key 'emp.username'
        // e.getCause()，获取真正触发的异常。 getMessage异常的提示信息
        String message = e.getCause().getMessage();
        String[] s = message.split(" ");//s[0]=>Duplicate,s[1]=>entry,s[2]=>'nazha',s[3]=>for,s[4]=>key,s[5]=>emp.username
        return Result.error("【" + s[2] + "】 已经存在了");
    }

    /**
     * 业务异常处理
     * @param e
     * @return
     */
    @ExceptionHandler(BizException.class)
    public Result handlerBizException(BizException e){
        return Result.error(e.getMessage());
    }

    @ExceptionHandler
    public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e){
        // 校验没通过的字段
        List<ObjectError> allErrors = e.getAllErrors();
        if(!CollectionUtils.isEmpty(allErrors)){
            /*StringJoiner joiner = new StringJoiner(",");//拼接字符串，以逗号分隔
            for (ObjectError error : allErrors) {
                //校验不通过时的提示信息
                String info = error.getDefaultMessage();
                joiner.add(info);
            }*/
            String errorInfo = allErrors.stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(";"));
            return Result.error(errorInfo);
        }
        return Result.error("参数校验失败");

    }

    @ExceptionHandler
    public Result handleHandlerMethodValidationException(HandlerMethodValidationException e){
        return Result.error(e.getAllErrors().stream().map(MessageSourceResolvable::getDefaultMessage).collect(Collectors.joining(";")));
    }
}
